#include "RulesProcessingUserMode.h"

class CTestMultiSZEnumObserver: public IMultiSZObserver
{
    public:
        CTestMultiSZEnumObserver()
        {
        }

        void OnMultiSZItemFound(const std::wstring& wsMultiSZItem)
        {
            vectWStr.push_back(wsMultiSZItem);
        }

        void ClearVector()
        {
            vectWStr.clear();
        }

        const std::vector<std::wstring>& GetVector()
        {
            return vectWStr;
        }

    private:
        CTestMultiSZEnumObserver(const CTestMultiSZEnumObserver&);
        CTestMultiSZEnumObserver& operator =(const CTestMultiSZEnumObserver&);

        std::vector<std::wstring> vectWStr;

};

void PrintList(const std::vector<std::wstring>& vectWStr)
{
    std::wcout<<"Register values:"<<std::endl;

    //Console output of register values
    for(DWORD i=0;i<vectWStr.size();++i)
    {
        std::wcout<<vectWStr.at(i)<<std::endl;
    }

    std::wcout<<std::endl;
}

int main(int argc, char* argv[])
{
    UNREFERENCED_PARAMETER(argc);
    UNREFERENCED_PARAMETER(argv);

    try
    {
        const wchar_t wsTestCaseKeyValue1[] = L"System\\CurrentControlSet\\Services\\FileHidingFilter\\MultiSZ1";

        // create test key and close handle in current scope
        {
            wchar_t wsTestCaseMultiSz1[] = L"case1\0case2\0case3\0\0";
            HKEY hKeyTemp = NULL;
            LONG lResult=RegCreateKeyW(HKEY_LOCAL_MACHINE, wsTestCaseKeyValue1, &hKeyTemp);

            if(lResult!=ERROR_SUCCESS)
            {
                throw std::runtime_error("Error key creation!");
            }

            KeyGuard keyGuard(hKeyTemp);
            unsigned char * pRawData = reinterpret_cast<unsigned char*>(&wsTestCaseMultiSz1[0]);
            LONG lRes=RegSetValueExW(keyGuard.getKey(), L"TestKey", 0, REG_MULTI_SZ, pRawData, sizeof(wsTestCaseMultiSz1));

            if(lRes!=ERROR_SUCCESS)
            {
                throw std::runtime_error("Error value adding!");
            }
        }

        CTestMultiSZEnumObserver observer;

        // enumerate created values
        EnumMultiSZValue(wsTestCaseKeyValue1, L"TestKey", &observer);

        // print enumerated list
        PrintList(observer.GetVector());

        std::wcout<<"Add new values to register..."<<std::endl;

        // add enumerated values to registry
        WriteMultiSZValue(wsTestCaseKeyValue1, L"TestKey", observer.GetVector());

        observer.ClearVector();

        // enumerate new values again after WriteMultiSZValue
        EnumMultiSZValue(wsTestCaseKeyValue1, L"TestKey", &observer);

        // print value and check 2 outputs
        PrintList(observer.GetVector());

        // TODO: rework for auto check without output

        return EXIT_SUCCESS;
    }
    catch ( std::exception &e ) 
    {
        std::wcerr << "Runtime error: " << e.what( ) << std::endl;

        return EXIT_FAILURE;
    }
}